home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume6 / glib / part09 < prev    next >
Encoding:
Text File  |  1989-05-14  |  42.7 KB  |  1,688 lines

  1. Newsgroups: comp.sources.misc
  2. From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  3. Subject: v06i110: glib part 9 of 15
  4. Reply-To: lee@uhccux.uhcc.Hawaii.Edu (Greg Lee )
  5.  
  6. Posting-number: Volume 6, Issue 110
  7. Submitted-by: lee@uhccux.uhcc.Hawaii.Edu (Greg Lee )
  8. Archive-name: glib/part09
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 9 (of 15)."
  17. # Contents:  dx7.mnu mac-vt.c
  18. # Wrapped by lee@uhccux on Sun May  7 00:40:16 1989
  19. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  20. if test -f 'dx7.mnu' -a "${1}" != "-c" ; then 
  21.   echo shar: Will not clobber existing file \"'dx7.mnu'\"
  22. else
  23. echo shar: Extracting \"'dx7.mnu'\" \(21054 characters\)
  24. sed "s/^X//" >'dx7.mnu' <<'END_OF_FILE'
  25. X/* $Id: dx7.mnu,v 1.6 89/05/06 17:13:22 lee Exp $
  26. X * GLIB - a Generic LIBrarian and editor for synths
  27. X *
  28. X * DX-7 routines
  29. X *
  30. X * Scott Snyder - ssnyder@citromeo.bitnet, ssnyder@romeo.caltech.edu
  31. X * $Log:    dx7.mnu,v $
  32. X * Revision 1.6  89/05/06  17:13:22  lee
  33. X * rel. to comp.sources.misc
  34. X * 
  35. X */
  36. X
  37. X#define VCED_SIZE 155
  38. X
  39. X#include "glib.h"
  40. X#include <ctype.h>
  41. X#include <math.h>
  42. X
  43. Xchar *visnum(), *visonoff(), *vism3num(), *viswave(), *vismono();
  44. Xchar *visfreq(), *visdx1a(), *visr2num();
  45. X
  46. Xchar *visxq(), *visxx(), *vism7num(), *visx7note(), *visx7crv();
  47. Xchar *visx7a(), *visx7wave(), *visx7brkpt();
  48. X
  49. Xchar *visxq1(), *visxq2(), *visxq3();
  50. Xchar *visxq4(), *visxq5(), *visxq6();
  51. Xchar *visxx1(), *visxx2(), *visxx3();
  52. Xchar *visxx4(), *visxx5(), *visxx6();
  53. X
  54. X#define RESERVESIZE 0
  55. X
  56. X/* This array contains arbitrary screen labels */
  57. Xstruct labelinfo Ldx7[] = {
  58. X#MENU
  59. X                      N: set name; q: quit; K: incr; J: decr; >: max; <: min  k
  60. X                      space: play autonote Pitch  %   Vol   %                h l
  61. X                                           Dur    %   Chan  %                 j
  62. X
  63. X    Atk  Sust1 Sust2  Rls        Fix/  Out De  Rat  Sens   Brk  Depth  Curve   
  64. XOP Rt Lv Rt Lv Rt Lv Rt Lv  Freq Ratio Lvl tun Scl Key Mod Pt   L  R   L    R  
  65. X-- -- -- -- -- -- -- -- -- ----- ----- --- --- --- --- --- ---- -- -- ---- ----
  66. X 1 %  %  %  %  %  %  %  %  %     %      %   %   %   %   %  %    %  %  %    %   
  67. X 2 %  %  %  %  %  %  %  %  %     %      %   %   %   %   %  %    %  %  %    %   
  68. X 3 %  %  %  %  %  %  %  %  %     %      %   %   %   %   %  %    %  %  %    %   
  69. X 4 %  %  %  %  %  %  %  %  %     %      %   %   %   %   %  %    %  %  %    %   
  70. X 5 %  %  %  %  %  %  %  %  %     %      %   %   %   %   %  %    %  %  %    %   
  71. X 6 %  %  %  %  %  %  %  %  %     %      %   %   %   %   %  %    %  %  %    %   
  72. XPE %  %  %  %  %  %  %  %
  73. X
  74. XAlgorithm   %                    LFO Speed    %        Osc. Sync          @
  75. X==============                   LFO Delay    %        Feedback           @
  76. X                                 LFO AM Depth %        Middle C           @
  77. X                                 LFO PM Depth %
  78. X                                 LFO Wave     %
  79. X                                 LFO Sync     %
  80. X                                 LFO PM Sense %
  81. X
  82. X
  83. X
  84. X
  85. X#END
  86. X-1,-1,NULL
  87. X};
  88. X
  89. X/* This array defines all the editable parameters. */
  90. Xstruct paraminfo Pdx7[] = {
  91. X"autopitch",    NULL, -1, -1, %%, visnum, 0, 127, 60, 0,
  92. X"autovol",    NULL, -1, -1, %%, visnum, 0, 127, 63, 0,
  93. X"autodur",    NULL, -1, -1, %%, visnum, 1,  20,  5, 0,
  94. X"autochan",    NULL, -1, -1, %%, visnum, 1,  16,  1, 0,
  95. X
  96. X/*NAME        TYPE        POS    MAX    OFFSET    MASK    SHIFT    ADHOC*/
  97. X#O op1atkrt    r2num        %%    99    85
  98. X#O op1atklv    r2num        %%    99    89
  99. X#O op1sust1rt    r2num        %%    99    86
  100. X#O op1sust1lv    r2num        %%    99    90
  101. X#O op1sust2rt    r2num        %%    99    87
  102. X#O op1sust2lv    r2num        %%    99    91
  103. X#O op1rlsrt    r2num        %%    99    88
  104. X#O op1rlslv    r2num        %%    99    92
  105. X#O op1freq    xq1        %%    4067    101            *3
  106. X#O op1coarsefq    num        --    255    100    0x3E    1    *4
  107. X#O op1fx    xx1        %%    1    100    0x01
  108. X#O op1outlevel    num        %%    99    99
  109. X#O op1detune    m7num        %%    14    97    0x78    3
  110. X#O op1ratscl    num        %%    7    97    0x07
  111. X#O op1tchsens    num        %%    7    98    0x1C    2
  112. X#O op1modsens    num        %%    3    98    0x03
  113. X#O op1brkpt    x7brkpt        %%    99    93
  114. X#O op1ldepth    r2num        %%    99    94
  115. X#O op1rdepth    r2num        %%    99    95
  116. X#O op1lcurve    x7crv        %%    3    96    0x03
  117. X#O op1rcurve    x7crv        %%    3    96    0x0C    2
  118. X
  119. X#O op2atkrt    r2num        %%    99    68
  120. X#O op2atklv    r2num        %%    99    72
  121. X#O op2sust1rt    r2num        %%    99    69
  122. X#O op2sust1lv    r2num        %%    99    73
  123. X#O op2sust2rt    r2num        %%    99    70
  124. X#O op2sust2lv    r2num        %%    99    74
  125. X#O op2rlsrt    r2num        %%    99    71
  126. X#O op2rlslv    r2num        %%    99    75
  127. X#O op2freq    xq2        %%    4067    84            *3
  128. X#O op2coarsefq    num        --    255    83    0x3E    1    *4
  129. X#O op2fx    xx2        %%    1    83    0x01
  130. X#O op2outlevel    num        %%    99    82
  131. X#O op2detune    m7num        %%    14    80    0x78    3
  132. X#O op2ratscl    num        %%    7    80    0x07
  133. X#O op2tchsens    num        %%    7    81    0x1C    2
  134. X#O op2modsens    num        %%    3    81    0x03
  135. X#O op2brkpt    x7brkpt        %%    99    76
  136. X#O op2ldepth    r2num        %%    99    77
  137. X#O op2rdepth    r2num        %%    99    78
  138. X#O op2lcurve    x7crv        %%    3    79    0x03
  139. X#O op2rcurve    x7crv        %%    3    79    0x0C    2
  140. X
  141. X#O op3atkrt    r2num        %%    99    51
  142. X#O op3atklv    r2num        %%    99    55
  143. X#O op3sust1rt    r2num        %%    99    52
  144. X#O op3sust1lv    r2num        %%    99    56
  145. X#O op3sust2rt    r2num        %%    99    53
  146. X#O op3sust2lv    r2num        %%    99    57
  147. X#O op3rlsrt    r2num        %%    99    54
  148. X#O op3rlslv    r2num        %%    99    58
  149. X#O op3freq    xq3        %%    4067    67            *3
  150. X#O op3coarsefq    num        --    255    66    0x3E    1    *4
  151. X#O op3fx    xx3        %%    1    66    0x01
  152. X#O op3outlevel    num        %%    99    65
  153. X#O op3detune    m7num        %%    14    63    0x78    3
  154. X#O op3ratscl    num        %%    7    63    0x07
  155. X#O op3tchsens    num        %%    7    64    0x1C    2
  156. X#O op3modsens    num        %%    3    64    0x03
  157. X#O op3brkpt    x7brkpt        %%    99    59
  158. X#O op3ldepth    r2num        %%    99    60
  159. X#O op3rdepth    r2num        %%    99    61
  160. X#O op3lcurve    x7crv        %%    3    62    0x03
  161. X#O op3rcurve    x7crv        %%    3    62    0x0C    2
  162. X
  163. X#O op4atkrt    r2num        %%    99    34
  164. X#O op4atklv    r2num        %%    99    38
  165. X#O op4sust1rt    r2num        %%    99    35
  166. X#O op4sust1lv    r2num        %%    99    39
  167. X#O op4sust2rt    r2num        %%    99    36
  168. X#O op4sust2lv    r2num        %%    99    40
  169. X#O op4rlsrt    r2num        %%    99    37
  170. X#O op4rlslv    r2num        %%    99    41
  171. X#O op4freq    xq4        %%    4067    50            *3
  172. X#O op4coarsefq    num        --    255    49    0x3E    1    *4
  173. X#O op4fx    xx4        %%    1    49    0x01
  174. X#O op4outlevel    num        %%    99    48
  175. X#O op4detune    m7num        %%    14    46    0x78    3
  176. X#O op4ratscl    num        %%    7    46    0x07
  177. X#O op4tchsens    num        %%    7    47    0x1C    2
  178. X#O op4modsens    num        %%    3    47    0x03
  179. X#O op4brkpt    x7brkpt        %%    99    42
  180. X#O op4ldepth    r2num        %%    99    43
  181. X#O op4rdepth    r2num        %%    99    44
  182. X#O op4lcurve    x7crv        %%    3    45    0x03
  183. X#O op4rcurve    x7crv        %%    3    45    0x0C    2
  184. X
  185. X#O op5atkrt    r2num        %%    99    17
  186. X#O op5atklv    r2num        %%    99    21
  187. X#O op5sust1rt    r2num        %%    99    18
  188. X#O op5sust1lv    r2num        %%    99    22
  189. X#O op5sust2rt    r2num        %%    99    19
  190. X#O op5sust2lv    r2num        %%    99    23
  191. X#O op5rlsrt    r2num        %%    99    20
  192. X#O op5rlslv    r2num        %%    99    24
  193. X#O op5freq    xq5        %%    4067    33            *3
  194. X#O op5coarsefq    num        --    255    32    0x3E    1    *4
  195. X#O op5fx    xx5        %%    1    32    0x01
  196. X#O op5outlevel    num        %%    99    31
  197. X#O op5detune    m7num        %%    14    29    0x78    3
  198. X#O op5ratscl    num        %%    7    29    0x07
  199. X#O op5tchsens    num        %%    7    30    0x1C    2
  200. X#O op5modsens    num        %%    3    30    0x03
  201. X#O op5brkpt    x7brkpt        %%    99    25
  202. X#O op5ldepth    r2num        %%    99    26
  203. X#O op5rdepth    r2num        %%    99    27
  204. X#O op5lcurve    x7crv        %%    3    28    0x03
  205. X#O op5rcurve    x7crv        %%    3    28    0x0C    2
  206. X
  207. X#O op6atkrt    r2num        %%    99    0
  208. X#O op6atklv    r2num        %%    99    4
  209. X#O op6sust1rt    r2num        %%    99    1
  210. X#O op6sust1lv    r2num        %%    99    5
  211. X#O op6sust2rt    r2num        %%    99    2
  212. X#O op6sust2lv    r2num        %%    99    6
  213. X#O op6rlsrt    r2num        %%    99    3
  214. X#O op6rlslv    r2num        %%    99    7
  215. X#O op6freq    xq6        %%    4067    16            *3
  216. X#O op6coarsefq    num        --    255    15    0x3E    1    *4
  217. X#O op6fx    xx6        %%    1    15    0x01
  218. X#O op6outlevel    num        %%    99    14
  219. X#O op6detune    m7num        %%    14    12    0x78    3
  220. X#O op6ratscl    num        %%    7    12    0x07
  221. X#O op6tchsens    num        %%    7    13    0x1C    2
  222. X#O op6modsens    num        %%    3    13    0x03
  223. X#O op6brkpt    x7brkpt        %%    99    8
  224. X#O op6ldepth    r2num        %%    99    9
  225. X#O op6rdepth    r2num        %%    99    10
  226. X#O op6lcurve    x7crv        %%    3    11    0x03
  227. X#O op6rcurve    x7crv        %%    3    11    0x0C    2
  228. X
  229. X#O pegatkrt    r2num        %%    99    102
  230. X#O pegatklv    r2num        %%    99    106
  231. X#O pegsust1rt    r2num        %%    99    103
  232. X#O pegsust1lv    r2num        %%    99    107
  233. X#O pegsust2rt    r2num        %%    99    104
  234. X#O pegsust2lv    r2num        %%    99    108
  235. X#O pegrlsrt    r2num        %%    99    105
  236. X#O pegrlslv    r2num        %%    99    109
  237. X
  238. X#O algorithm    x7a        %%    31    110    0x1F
  239. X
  240. X#O lfospeed    num        %%    99    112
  241. X#O lfodelay    num        %%    99    113
  242. X#O lfoamdepth    num        %%    99    115
  243. X#O lfopmdepth    num        %%    99    114
  244. X#O lfowave    x7wave        %%    5    116    0x0E    1
  245. X#O lfosync    onoff        %%    1    116    0x01
  246. X#O lfopmsens    num        %%    7    116    0x70    4
  247. X
  248. X#O oscsync    onoff        @@    1    111    0x08    3
  249. X#O feedback    num        @@    7    111    0x07
  250. X#O transpose    x7note        @@    48    117
  251. X
  252. XNULL,    NULL, -1, -1, -1, -1, visnum, 0, 0, 0, 0
  253. X};
  254. X
  255. X/*
  256. X#ifdef __TURBOC__
  257. X# pragma warn -par
  258. X#endif
  259. X*/
  260. X
  261. X#if !defined(TX81Z) && !defined(TX81ZPERF) && !defined(DX100)
  262. X
  263. X/* else these routines are in yama_com */
  264. X
  265. Xsetopval(n,str,v)
  266. Xchar *str;
  267. X{
  268. X    char buff[32];
  269. X    (void)sprintf(buff,"op%d%s",n,str);
  270. X    setval(buff,v);
  271. X}
  272. X
  273. X/* not used
  274. Xgetopval(n,str)
  275. Xchar *str;
  276. X{
  277. X    char buff[32];
  278. X    (void)sprintf(buff,"op%d%s",n,str);
  279. X    return(getval(buff));
  280. X}
  281. X*/
  282. X
  283. Xchar *
  284. Xvismono(v)
  285. X{
  286. X    if ( v==0 )
  287. X        return("poly");
  288. X    else
  289. X        return("mono");
  290. X}
  291. X
  292. X#endif
  293. X
  294. Xchar *vism7num(v)
  295. Xint v;
  296. X{
  297. X  static char Nbuff[16];
  298. X
  299. X  (void)sprintf(Nbuff, "%d", v-7);
  300. X  return Nbuff;
  301. X}
  302. X
  303. X/* 2-digit, right-justified */
  304. Xchar *visr2num(v)
  305. Xint v;
  306. X{
  307. X  static char Nbuff[16];
  308. X
  309. X  (void)sprintf(Nbuff, "%2d", v);
  310. X  return Nbuff;
  311. X}
  312. X
  313. Xchar *Dx7Notes[] =
  314. X { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" };
  315. X
  316. Xchar *visx7note(v)
  317. Xint v;
  318. X{
  319. X  int oct, tone;
  320. X  char *p;
  321. X  static char buf[8];
  322. X
  323. X  oct = floor((double)v / 12.0);
  324. X  tone = v - oct*12;
  325. X
  326. X  strcpy(buf, Dx7Notes[tone]);
  327. X  p = buf + (buf[1] == 0 ? 1 : 2);
  328. X  (void)sprintf(p, "%d", oct+1);
  329. X
  330. X  return buf;
  331. X}
  332. X
  333. Xchar *visx7brkpt(v)
  334. Xint v;
  335. X{
  336. X  return visx7note(v - 15);
  337. X}
  338. X
  339. Xchar *visx7crv(v)
  340. Xint v;
  341. X{
  342. X  switch (v) {
  343. X    case 0: return "-LIN";
  344. X    case 1: return "-EXP";
  345. X    case 2: return "+EXP";
  346. X    case 3: return "+LIN";
  347. X    default: return "???";
  348. X  }
  349. X}
  350. X
  351. Xchar *visx7wave(v)
  352. Xint v;
  353. X{
  354. X  switch (v) {
  355. X    case 0: return "Tri";
  356. X    case 1: return "Saw Down";
  357. X    case 2: return "Saw Up";
  358. X    case 3: return "Square";
  359. X    case 4: return "Sine";
  360. X    case 5: return "S/Hold";
  361. X    default: return "???";
  362. X  }
  363. X}
  364. X
  365. Xchar *visxqr(c, f)
  366. Xint c, f;
  367. X{
  368. X  static char buf[8];
  369. X  float freq;
  370. X
  371. X  freq = c;
  372. X  if (c == 0) freq = 0.5;
  373. X
  374. X  freq += f * freq / 100;
  375. X
  376. X  (void)sprintf(buf, "%5.2f", freq);
  377. X  return buf;
  378. X}
  379. X
  380. Xint Dx7Freqs[] = {
  381. X  1000, 1023, 1047, 1072, 1096, 1122, 1148, 1175, 1202, 1230,
  382. X  1259, 1288, 1318, 1349, 1380, 1413, 1445, 1479, 1514, 1549,
  383. X  1585, 1622, 1660, 1698, 1738, 1778, 1820, 1862, 1905, 1950,
  384. X  1995, 2042, 2089, 2138, 2188, 2239, 2291, 2344, 2399, 2455,
  385. X  2512, 2570, 2630, 2692, 2716, 2818, 2884, 2951, 3020, 3090,
  386. X  3162, 3236, 3311, 3388, 3467, 3548, 3631, 3715, 3802, 3890,
  387. X  3981, 4074, 4169, 4266, 4365, 4467, 4571, 4677, 4786, 4898,
  388. X  5012, 5129, 5248, 5370, 5495, 5623, 5754, 5888, 6026, 6166,
  389. X  6310, 6457, 6607, 6761, 6918, 7079, 7244, 7413, 7586, 7762,
  390. X  7943, 8128, 8318, 8511, 8718, 8913, 9120, 9333, 9550, 9772,
  391. X};
  392. X
  393. Xchar *visxqf(c, f)
  394. Xint c, f;
  395. X{
  396. X  static char buf[8];
  397. X  int i;
  398. X
  399. X  c %= 4;
  400. X
  401. X  (void)sprintf(buf, "%4d ", Dx7Freqs[f]);
  402. X
  403. X  if (c < 3) {
  404. X    for (i=4; i>c; i--)
  405. X      buf[i+1] = buf[i];
  406. X    buf[c+1] = '.';
  407. X  }
  408. X
  409. X  return buf;
  410. X}
  411. X
  412. Xchar *visxq(v, op)
  413. Xint v, op;
  414. X{
  415. X  char buff[8];
  416. X  int c, f;
  417. X
  418. X  c = v / 128;
  419. X  f = v % 128;
  420. X
  421. X  if (f > 99) {
  422. X    if (f > 110) {
  423. X      f = 99;
  424. X    }
  425. X    else {
  426. X      c++;
  427. X      f = 0;
  428. X    }
  429. X    setopval(op, "freq", c*128 + f);
  430. X  }
  431. X
  432. X  (void)sprintf(buff, "op%dfx", op);
  433. X  if (getval(buff) == 0)
  434. X    return visxqr(c, f);
  435. X  else
  436. X    return visxqf(c, f);
  437. X}
  438. X
  439. Xchar *visxx(v, op, s)   /* s == 1 for a DX7s */
  440. Xint v, op, s;
  441. X{
  442. X  static int lastfx[] = { 0, -1, -1, -1, -1, -1, -1 };
  443. X  char buff2[8];
  444. X  int fqindex;
  445. X
  446. X  if ( lastfx[op] != -1 && lastfx[op] == v )
  447. X    goto nochange;
  448. X
  449. X  lastfx[op] = v;
  450. X  (void)sprintf(buff2,"op%dfreq",op);
  451. X  fqindex = parmindex(buff2);
  452. X  showparam(fqindex,0);
  453. Xnochange:
  454. X  if ( v == 0 )
  455. X    return(s ? " R" : "Ratio");
  456. X  else
  457. X    return(s ? "Hz" : "Fixed");
  458. X}
  459. X
  460. Xchar *visxx1(v) { return visxx(v, 1, 0); }
  461. Xchar *visxx2(v) { return visxx(v, 2, 0); }
  462. Xchar *visxx3(v) { return visxx(v, 3, 0); }
  463. Xchar *visxx4(v) { return visxx(v, 4, 0); }
  464. Xchar *visxx5(v) { return visxx(v, 5, 0); }
  465. Xchar *visxx6(v) { return visxx(v, 6, 0); }
  466. X
  467. Xchar *visxq1(v) { return visxq(v, 1); }
  468. Xchar *visxq2(v) { return visxq(v, 2); }
  469. Xchar *visxq3(v) { return visxq(v, 3); }
  470. Xchar *visxq4(v) { return visxq(v, 4); }
  471. Xchar *visxq5(v) { return visxq(v, 5); }
  472. Xchar *visxq6(v) { return visxq(v, 6); }
  473. X
  474. X/*
  475. X  6+--5   6---5   3   6+   3   6+
  476. X  ++  |       |   |   ++   |   ||
  477. X  2   4   2+  4   2   5    2   5|   2   4   6+   2   4   6+
  478. X  |   |   ++  |   |   |    |   ||   |   |   ++   |   |   ||
  479. X  1   3   1   3   1   4    1   4|   1   3   5    1   3   5|
  480. X  +-+-+   +-+-+   +-+-+    +-+-++   +---+---+    +---+---++
  481. X    1       2       3        4          5            6
  482. X
  483. X          6+           6           6           3+           3
  484. X          ++           |           |           ++           |
  485. X  2   4   5    2  +4   5   2+  4   5   5   6   2    5   6+  2
  486. X  |   |   |    |  ++   |   ++  |   |   |   |   |    |   ++  |
  487. X  1   3---+    1   3---+   1   3---+   +---4   1    +---4   1
  488. X  +-+-+        +-+-+       +-+-+           +-+-+        +-+-+
  489. X    7            8           9               10           11
  490. X
  491. X                             5--+6+   5--+6      4  6+      4  6
  492. X  4  5  6  2+   4  5  6+ 2      |++      ||      |  ++      |  |
  493. X  |  |  |  ++   |  |  ++ |   2  +4    2+ +4   2  3  5    2+ 3  5
  494. X  +--3--+  1    +--3--+  1   |   |    ++  |   |  |  |    ++ |  |
  495. X     |     |       |     |   1   3    1   3   +--1--+    +--1--+
  496. X     +--+--+       +--+--+   +-+-+    +-+-+      |          |
  497. X        12            13       14       15       16         17
  498. X
  499. X      6---5   3
  500. X          |   | 
  501. X  2   3+  4   2  +6       3+  5-+ 6   3+      6   2      6+
  502. X  |   ++  |   |  ++---+   ++--+ | |  ++++   +-++  |  +---++-+
  503. X  +---1---+   1   4   5   1   2 +-4  1  2   4  5  1  3   4  5
  504. X      |       +---+---+   +---+---+  +--+-+-+--+  +--+-+-+--+
  505. X      18          19          20          21           22
  506. X
  507. X     3    6+         6+         6+      3   5  6+    3+  5  6+
  508. X     |   ++++      +-+++        +++     |   |  ++    ++  |  ++
  509. X  1  2   4  5  1 2 3 4 5  1 2 3 4 5  1  2   +--4  1  2   +--4
  510. X  +--+-+-+--+  +-+-+-+-+  +-+-+-+-+  +--+-+-+--+  +--+-+-+--+
  511. X       23          24         25          26           27
  512. X
  513. X      5+                          5+
  514. X      ++                          ++
  515. X  2   4             4  6+         4             6+
  516. X  |   |             |  ++         |             ++
  517. X  1   3   6  1  2   3  5   1  2   3  6  1 2 3 4 5   1 2 3 4 5 6+
  518. X  +---+---+  +--+-+-+--+   +--+-+-+--+  +-+-+-+-+   +-+-+-+-+-++
  519. X      28          29            30          31            32
  520. X*/
  521. X
  522. Xchar *Dx7Algstr[] = {
  523. X"1 ~3d~10l6~T~-~-5~n~[~]  ~|~n2   4~n~|   ~|~n1   3~n~[~-~T~-~]",
  524. X"2 ~3d~10l6~-~-~-5~n    ~|~n2~}  4~n~>~]  ~|~n1   3~n~[~-~T~-~]",
  525. X"3 ~3d~10l3   6~}~n~|   ~>~]~n2   5~n~|   ~|~n1   4~n~[~-~T~-~]",
  526. X"4 ~3d~10l3   6~}~n~|   ~|~|~n2   5~|~n~|   ~|~|~n1   4~|~n~[~-~T~-~^~]",
  527. X"5 ~5d~12l2   4   6~}~n~|   ~|   ~>~]~n1   3   5~n~[~3-~+~3-~]",
  528. X"6 ~5d~12l2   4   6~}~n~|   ~|   ~|~|~n1   3   5~|~n~[~3-~+~3-~^~]",
  529. X"7 ~3d~12l~8 6~}~n~8 ~>~]~n2   4   5~n~|   ~|   ~|~n1   3~3-~]~n~[~-~T~-~]",
  530. X"8 ~3d~12l~8 6~n~8 ~|~n2  ~{4   5~n~|  ~[~<   ~|~n1   3~3-~]~n~[~-~T~-~]",
  531. X"9 ~3d~12l~8 6~n~8 ~|~n2~}  4   5~n~>~]  ~|   ~|~n1   3~3-~]~n~[~-~T~-~]",
  532. X"10~3d~12l~8 3~}~n~8 ~>~]~n5   6   2~n~|   ~|   ~|~n~[~3-4   1~n~4 ~[~-~T~-~]",
  533. X"11~3d~12l~8 3~n~8 ~|~n5   6~}  2~n~|   ~>~]  ~|~n~[~3-4   1~n~4 ~[~-~T~-~]",
  534. X"12~4d~13l4  5  6  2~}~n~|  ~|  ~|  ~>~]~n~[~2-3~2-~]  1~n   ~|~5 ~|~n   ~[~2-~T~2-~]",
  535. X"13~4d~13l4  5  6~} 2~n~|  ~|  ~>~] ~|~n~[~2-3~2-~]  1~n   ~|~5 ~|~n   ~[~2-~T~2-~]",
  536. X"14~3d~10l5~2-~}6~}~n   ~|~>~]~n2  ~[4~n~|   ~|~n1   3~n~[~-~T~-~]",
  537. X"15~3d~10l5~2-~}6~n   ~|~|~n2~} ~[4~n~>~]  ~|~n1   3~n~[~-~T~-~]",
  538. X"16~3d~11l   4  6~}~n   ~|  ~>~]~n2  3  5~n~|  ~|  ~|~n~[~2-1~2-~]~n   ~|",
  539. X"17~3d~11l   4  6~n   ~|  ~|~n2~} 3  5~n~>~] ~|  ~|~n~[~2-1~2-~]~n   ~|",
  540. X"18~3d~12l~4 6~3-5~n~8 ~|~n2   3~}  4~n~|   ~>~]  ~|~n~[~3-1~3-~]~n~4 ~|",
  541. X"19~3d~12l3~n~|~n2  ~{6~n~|  ~[~+~3-~}~n1   4   5~n~[~3-~+~3-~]",
  542. X"20~5d~12l3~}  5~-~} 6~n~>~^~2-~} ~| ~|~n1   2 ~[~-4~n~[~3-~+~3-~]",
  543. X"21~5d~13l 3~}~6 6~n~{~^~^~}   ~{~-~^~}~n1  2   4  5~n~[~2-~^~-~T~-~^~2-~]",
  544. X"22~5d~13l2~6 6~}~n~|  ~{~3-~+~^~-~}~n1  3   4  5~n~[~2-~^~-~T~-~^~2-~]",
  545. X"23~5d~13l   3    6~}~n   ~|   ~{~^~^~}~n1  2   4  5~n~[~2-~^~-~T~-~^~2-~]",
  546. X"24~5d~13l~6 6~}~n    ~{~-~+~^~}~n1 2 3 4 5~n~[~-~^~-~+~-~^~-~]",
  547. X"25~5d~13l~6 6~}~n~6 ~>~^~}~n1 2 3 4 5~n~[~-~^~-~+~-~^~-~]",
  548. X"26~5d~13l   3   5  6~}~n   ~|   ~|  ~>~]~n1  2   ~[~2-4~n~[~2-~^~-~T~4-~]",
  549. X"27~5d~13l   3~}  5  6~}~n   ~>~]  ~|  ~>~]~n1  2   ~[~2-4~n~[~2-~^~-~T~4-~]",
  550. X"28~3d~12l~4 5~}~n~4 ~>~]~n2   4~n~|   ~|~n1   3   6~n~[~3-~+~3-~]",
  551. X"29~5d~13l~7 4  6~}~n~7 ~|  ~>~]~n1  2   3  5~n~[~2-~^~-~T~-~^~2-~]",
  552. X"30~3d~13l~7 5~}~n~7 ~>~]~n~7 4~n~7 ~|~n1  2   3  6~n~[~2-~^~-~T~-~^~2-~]",
  553. X"31~5d~12l~8 6~}~n~8 ~>~]~n1 2 3 4 5~n~[~-~^~-~+~-~^~-~]",
  554. X"32~7d~13l1 2 3 4 5 6~}~n~[~-~^~-~^~-~+~-~^~-~^~]",
  555. X};
  556. X
  557. Xchar *visx7a(v)
  558. Xint v;
  559. X{
  560. X  if (v >= 0 && v < sizeof(Dx7Algstr)/sizeof(char *))
  561. X    return(Dx7Algstr[v]);
  562. X  else
  563. X    return("????");
  564. X}
  565. X
  566. Xdx7din(data)
  567. Xchar *data;
  568. X{
  569. X#SETVAL
  570. X}
  571. X
  572. Xdx7dout(data)
  573. Xchar *data;
  574. X{
  575. X#GETVAL
  576. X
  577. X  Channel = getval("autochan");
  578. X}
  579. X
  580. Xchar *dx7nof(data)
  581. Xchar *data;
  582. X{
  583. X  static char buf[11];
  584. X  char *p;
  585. X  int i;
  586. X
  587. X  p = buf;
  588. X  for (i=118; i<=127; i++)
  589. X    *p++ = data[i];
  590. X
  591. X  *p = '\0';
  592. X
  593. X  return buf;
  594. X}
  595. X
  596. Xdx7snof(data, name)
  597. Xchar *data, *name;
  598. X{
  599. X  int i;
  600. X
  601. X  for (i=118; i<=127 && *name; i++)
  602. X    data[i] = *name++;
  603. X  for (; i<=127; i++)
  604. X    data[i] = ' ';
  605. X}
  606. X
  607. Xdx7vmemtovced(in, out)
  608. Xchar *in, *out;
  609. X{
  610. X  int i;
  611. X  char *opin, *opout;
  612. X
  613. X  for (i=0; i<6; i++) {
  614. X    opin = in + (6-i-1)*17;
  615. X    opout = out + (6-i-1)*21;
  616. X
  617. X    opout[ 0] = opin[ 0];        /* eg rate 1 */
  618. X    opout[ 1] = opin[ 1];        /* eg rate 2 */
  619. X    opout[ 2] = opin[ 2];        /* eg rate 3 */
  620. X    opout[ 3] = opin[ 3];        /* eg rate 4 */
  621. X    opout[ 4] = opin[ 4];        /* eg level 1 */
  622. X    opout[ 5] = opin[ 5];        /* eg level 2 */
  623. X    opout[ 6] = opin[ 6];        /* eg level 3 */
  624. X    opout[ 7] = opin[ 7];        /* eg level 4 */
  625. X    opout[ 8] = opin[ 8];        /* breakpoint */
  626. X    opout[ 9] = opin[ 9];        /* l. depth */
  627. X    opout[10] = opin[10];        /* r. depth */
  628. X    opout[11] = opin[11] & 0x03;    /* l. curve */
  629. X    opout[12] = (opin[11]>>2) & 0x03;    /* r. curve */
  630. X    opout[13] = opin[12] & 0x07;    /* rate scaling */
  631. X    opout[14] = opin[13] & 0x03;    /* mod. sens. */
  632. X    opout[15] = (opin[13]>>2) & 0x07;    /* touch sens. */
  633. X    opout[16] = opin[14];        /* total level */
  634. X    opout[17] = opin[15] & 0x01;    /* freq. mode */
  635. X    opout[18] = (opin[15]>>1) & 0x1f;    /* coarse freq. */
  636. X    opout[19] = opin[16];        /* fine freq. */
  637. X    opout[20] = (opin[12]>>3) & 0x0f;    /* detune */
  638. X  }
  639. X
  640. X  out[126] = in[102];            /* peg rate 1 */
  641. X  out[127] = in[103];            /* peg rate 2 */
  642. X  out[128] = in[104];            /* peg rate 3 */
  643. X  out[129] = in[105];            /* peg rate 4 */
  644. X  out[130] = in[106];            /* peg level 1 */
  645. X  out[131] = in[107];            /* peg level 2 */
  646. X  out[132] = in[108];            /* peg level 3 */
  647. X  out[133] = in[109];            /* peg level 4 */
  648. X  out[134] = in[110] & 0x1f;        /* algorithm */
  649. X  out[135] = in[111] & 0x07;        /* feedback */
  650. X  out[136] = (in[111]>>3) & 0x01;    /* osc sync */
  651. X  out[137] = in[112];            /* lfo speed */
  652. X  out[138] = in[113];            /* lfo delay time */
  653. X  out[139] = in[114];            /* pm depth */
  654. X  out[140] = in[115];            /* am depth */
  655. X  out[141] = in[116] & 0x01;        /* lfo key sync */
  656. X  out[142] = (in[116]>>1) & 0x07;    /* lfo wave */
  657. X  out[143] = (in[116]>>4) & 0x0f;    /* lfo pm sens */
  658. X  out[144] = in[117];            /* transpose */
  659. X
  660. X  for (i=0; i<10; i++)
  661. X    out[145+i] = in[118+i];        /* name */
  662. X}
  663. X
  664. Xdx7send_bulk(format, length, data)
  665. Xint format, length;
  666. Xchar *data;
  667. X{
  668. X  int csum, i;
  669. X
  670. X  sendmidi(0xf0);
  671. X  sendmidi(0x43);
  672. X  sendmidi(Channel-1);
  673. X  sendmidi(format);
  674. X  sendmidi(length / 128);
  675. X  sendmidi(length % 128);
  676. X
  677. X  csum = 0;
  678. X  for (i=0; i<length; i++) {
  679. X    sendmidi(data[i]);
  680. X    csum += data[i];
  681. X  }
  682. X
  683. X  sendmidi((-csum) & 0x7f);
  684. X  sendmidi(EOX);
  685. X
  686. X  return 0;
  687. X}
  688. X
  689. Xdx7svced(data)
  690. Xchar *data;
  691. X{
  692. X  return dx7send_bulk(0, VCED_SIZE, data);
  693. X}
  694. X
  695. Xdx7sedit(data)
  696. Xchar *data;
  697. X{
  698. X  char edmem[VCED_SIZE];
  699. X
  700. X  dx7vmemtovced(data, edmem);
  701. X  return dx7svced(edmem);
  702. X}
  703. X
  704. Xdx7sbulk(data)
  705. Xchar *data;
  706. X{
  707. X  return dx7send_bulk(9, 4096, data);
  708. X}
  709. X
  710. Xdx7get_bulk(format, maxlength, data)
  711. Xint format;
  712. Xunsigned maxlength;
  713. Xchar *data;
  714. X{
  715. X  int c, n, b1, b2, cksum, ret = 1;
  716. X  unsigned len;
  717. X  long begin, toolong;
  718. X  static char ckbuff[80];
  719. X
  720. X  flushmidi();
  721. X
  722. X  begin = milliclock();
  723. X  toolong = begin + 1000 * TIMEOUT;
  724. X
  725. X  sendmidi(0xf0);
  726. X  sendmidi(0x43);
  727. X  sendmidi(0x20 | (Channel-1) );    /* Channel # */
  728. X  sendmidi(format);            /* 4 == 32 voice bulk dump */
  729. X  sendmidi(EOX);            /* EOX */
  730. X
  731. X#ifdef BYTEBOARD
  732. X/*
  733. X# ifdef __TURBOC__
  734. X#  pragma warn -rch
  735. X# endif
  736. X*/
  737. X  if (midi_getsex(toolong) == NULL) return 1;
  738. X#endif
  739. X
  740. X  /* wait for the x43 byte starting the dump */
  741. X  c = 0;
  742. X  while ( milliclock() < toolong ) {
  743. X    if ( STATMIDI && (c=(getmidi() & 0xff)) == 0x43 )
  744. X      break;
  745. X  }
  746. X  if ( c != 0x43 ) {
  747. X    Reason = "Timeout waiting for 0x43";
  748. X    goto getout;
  749. X  }
  750. X
  751. X  (void)getmidi();        /* channel # */
  752. X  c = getmidi();    /* format # */
  753. X  if (c != format) {
  754. X    (void)sprintf(ckbuff, "Synth sent format %d instead of %d", c, format);
  755. X    Reason = ckbuff;
  756. X    goto getout;
  757. X  }
  758. X  len = 128 * getmidi();    /* byte count high byte */
  759. X  len += getmidi();        /* byte count low byte */
  760. X  if (len > maxlength) {
  761. X    Reason = "Synth sent more data than I was expecting";
  762. X    goto getout;
  763. X  }
  764. X
  765. X  cksum = 0;
  766. X  /* 32 voices are dumped */
  767. X  for (n=0; n<len; n++) {
  768. X    /* twiddle your thumbs, but not forever */
  769. Xanotherch:
  770. X    while ( ! STATMIDI ) {
  771. X      if ( milliclock() > toolong )
  772. X        goto timeout;    /* the end of an era */
  773. X    }
  774. X    c = (getmidi() & 0xff);
  775. X    /* Ignore non-data bytes ? */
  776. X    if ( c & 0x80 )
  777. X      goto anotherch;
  778. X    /* compute checksum */
  779. X    cksum += c;
  780. X    data[n] = c;
  781. X  }
  782. Xtimeout:
  783. X  if ( n < len ) {
  784. X    Reason = "Timeout while reading!";
  785. X    goto getout;
  786. X  }
  787. X  b1 = (getmidi() & 0xff);    /* Checksum */
  788. X  b2 = (getmidi() & 0xff);    /* EOX */
  789. X  cksum = (-cksum) & 0x7f;    /* convert to what we must match */
  790. X  if ( b2 != EOX )
  791. X    Reason = "EOX not received";
  792. X  else if ( b1 != cksum ) {
  793. X    (void)sprintf(ckbuff,"Checksum doesn't match (got %d expected %d)",b1,cksum);
  794. X    Reason = ckbuff;
  795. X  }
  796. X  else {
  797. X    Reason = "";
  798. X    ret = 0;    /* all's well */
  799. X  }
  800. Xgetout:
  801. X  return(ret);
  802. X}
  803. X
  804. Xdx7gbulk(data)
  805. Xchar *data;
  806. X{
  807. X  return dx7get_bulk(9, 4096, data);
  808. X}
  809. END_OF_FILE
  810. if test 21054 -ne `wc -c <'dx7.mnu'`; then
  811.     echo shar: \"'dx7.mnu'\" unpacked with wrong size!
  812. fi
  813. # end of 'dx7.mnu'
  814. fi
  815. if test -f 'mac-vt.c' -a "${1}" != "-c" ; then 
  816.   echo shar: Will not clobber existing file \"'mac-vt.c'\"
  817. else
  818. echo shar: Extracting \"'mac-vt.c'\" \(19069 characters\)
  819. sed "s/^X//" >'mac-vt.c' <<'END_OF_FILE'
  820. X/* $Id: mac-vt.c,v 1.6 89/05/06 17:13:35 lee Exp $
  821. X**
  822. X** vt.c - a replacement dev:console driver for the Keynote musical expression
  823. X**        language.
  824. X**
  825. X** Provides a cursor, constant-width characters, and (someday) all the escape
  826. X** sequences for vt100 emulation.  The driver (handler) is installed at
  827. X** run-time (for MPW 1.0) by doing the following call (before doing any I/O,
  828. X** since that would auto-initialize the default system driver). 
  829. X**
  830. X** _addDevHandler(1, 'CONS', vt_faccess, vt_close, vt_read, vt_write, vt_ioctl);
  831. X**
  832. X** WARNING: this code assumes the MPW 1.0 development system.  It hooks itself
  833. X** in as a device driver using the undocumented _addDevHandler call, which
  834. X** may change in future releases of MPW.  It expects the system driver to be
  835. X** in slot 1 - this also may change.
  836. X**
  837. X** If you are not using MPW, some or all of this driver may be unnecessary.
  838. X** The vt_getch and vt_peekch functions probably ARE necessary and probably
  839. X** work correctly under any development system.  They mainly provide the 
  840. X** ability to stat the console to do non-blocking input.  They completely
  841. X** avoid MPW's stdio (and all other libraries for that matter), although
  842. X** the vt_read call provides an stdio interface if desired (blocking input
  843. X** only, of course).  They DO assume that the mac has been initialized and
  844. X** the event queue has been set up (InitGraf et.al.).
  845. X**
  846. X** The problem is printf.  If your development system has an acceptable
  847. X** implementation (MPW *does NOT*), then just comment out the definition
  848. X** of MPW in Keynote source file machdep.h and give 'er a try.  If, however,
  849. X** you want to use my vt_putch or vt_write routines, you will have to figure
  850. X** out how to hook them into your system. The only thing to beware of is to
  851. X** call vt_open before using vt_putch.  This is done automatically via the
  852. X** vt_faccess call for MPW 1.0.
  853. X**
  854. X** Steven A. Falco  4/30/87  moss!saf
  855. X*/
  856. X#include <types.h>
  857. X#include <quickdraw.h>
  858. X#include <toolutils.h>
  859. X#include <fonts.h>
  860. X#include <events.h>
  861. X#include <windows.h>
  862. X#include <dialogs.h>
  863. X#include <menus.h>
  864. X#include <desk.h>
  865. X#include <textedit.h>
  866. X#include <scrap.h>
  867. X#include <segload.h>
  868. X#include <resources.h>
  869. X#include <osutils.h>
  870. X#include <ioctl.h>
  871. X#include <fcntl.h>
  872. X#include "vt.h"
  873. X#include <stdio.h>
  874. X
  875. X#define MAXROW        24
  876. X#define MAXCOL        80
  877. X#define TABVAL        8
  878. X
  879. X#define ENONE        0
  880. X#define EFIRST        1
  881. X#define EBRACKET    2
  882. X
  883. X/* note - the pixel location is based on the character baseline. */
  884. X#define    XL(x)    ((x) * vt_font.widMax + 4)    /* x offset from chars to pixels */
  885. X#define    YL(y)    (((y) + 1) * vt_line - 2)      /* y offset from chars to pixels */
  886. X#define HOP        MoveTo(XL(vt_col), YL(vt_row)); GetPen(&vt_pen)
  887. X
  888. X/* BLANK(1,1) scrubs one cell.  (1,2) does a cell and the cell below it,
  889. X * while (2,1) does a cell and the cell to the right of it.  etc.
  890. X */
  891. X#define BLANK(i, j) SetRect(&vt_one_char, vt_pen.h, vt_pen.v - vt_above, \
  892. X                  vt_pen.h + (i) * vt_font.widMax, \
  893. X                  vt_pen.v + vt_below + ((j) - 1) * vt_line); \
  894. X                  EraseRect(&vt_one_char)
  895. X                  
  896. X#define CURSOR    SetRect(&vt_one_char, vt_pen.h, vt_pen.v - vt_above, \
  897. X                  vt_pen.h + vt_font.widMax, vt_pen.v + vt_below); \
  898. X                  PenMode(patXor); \
  899. X                  PaintRect(&vt_one_char); \
  900. X                  PenMode(patCopy)
  901. X
  902. X#define SAVE    vt_saverow = vt_row; vt_savecol = vt_col
  903. X
  904. X#define RESTORE    vt_row = vt_saverow; vt_col = vt_savecol
  905. X
  906. XWindowPtr    vt;
  907. XFontInfo    vt_font;
  908. Xint         vt_line, vt_above, vt_below;
  909. Xint            vt_col, vt_savecol;
  910. Xint            vt_row, vt_saverow;
  911. XRect        vt_one_char;
  912. XRect        vt_rect;
  913. XRect        screenRect;
  914. XPoint        vt_pen;
  915. Xint            vt_rawf;
  916. Xint            vt_esc;
  917. Xint            vt_inprog;        /* number in progress */
  918. Xint            vt_x, vt_y;        /* for motion escape code */
  919. X
  920. Xstatic int    firsttime = 0;
  921. Xstatic int    linesize = 0;
  922. Xstatic char    *lineptr;
  923. Xstatic char    linebuf[256];
  924. X
  925. X/* initialize the world.  We call this based on the "firsttime" flag - not an
  926. X * every faccess call! - we only want to do it once...
  927. X */
  928. Xvt_open()
  929. X{
  930. X    char *vt_title;
  931. X    int i;
  932. X
  933. X    InitGraf(&qd.thePort);
  934. X    InitFonts();
  935. X    FlushEvents(everyEvent, 0);
  936. X    InitWindows();
  937. X    InitMenus();
  938. X    TEInit();
  939. X    InitDialogs(nil);
  940. X    InitCursor();
  941. X    
  942. X    vt_title = "";
  943. X    screenRect = qd.screenBits.bounds;
  944. X    SetRect(&vt_rect, 4, 20 + 4, screenRect.right - 4, screenRect.bottom - 4);
  945. X    vt = NewWindow(nil, &vt_rect, vt_title, true, plainDBox, -1, false, 0);
  946. X    SetPort(vt);
  947. X    vt_rect.left -= 4; /* make vt_rect local - only used for scrolls hereafter */
  948. X    vt_rect.right -= 4;
  949. X    vt_rect.top -= (20 + 4);
  950. X    vt_rect.bottom -= (20 + 4);
  951. X    
  952. X    TextFont(monaco); /* this driver only supports constant-width */
  953. X    TextSize(9);
  954. X    GetFontInfo(&vt_font);
  955. X    PenMode(patCopy);
  956. X    vt_line = vt_font.ascent + vt_font.descent + vt_font.leading;
  957. X    vt_above = vt_font.ascent; /* dereference structure for efficiency */
  958. X    vt_below = vt_font.descent;
  959. X    vt_rawf = 0;            /* start out cooked */
  960. X    vt_esc = ENONE;            /* no escape sequence yet */
  961. X    
  962. X    vt_row = vt_col = 0;    /* start out at home */
  963. X    HOP;                    /* actually move there */
  964. X    CURSOR;                    /* put up a cursor (XOR) */
  965. X
  966. X    return;
  967. X}
  968. X
  969. X/* scroll the whole screen up one line-height */
  970. Xvt_scroll()
  971. X{
  972. X    RgnHandle scroll_rgn;
  973. X    
  974. X    scroll_rgn = NewRgn();
  975. X    ScrollRect(&vt_rect, 0, -vt_line, scroll_rgn);
  976. X    DisposeRgn(scroll_rgn);
  977. X    
  978. X    return;
  979. X}
  980. X
  981. X/* put a character on the screen.  Set state flags so we can process sequences
  982. X * of characters (to do escape sequences.)
  983. X * Assume we are sitting on the cursor and vt_pen is valid
  984. X */
  985. Xvt_putch(c)
  986. X    int c;
  987. X{
  988. X    if(vt_esc > ENONE) { /* we are in the middle of an escape sequence */
  989. X        escape_code(c);
  990. X    } else if(c >= ' ' && c <= '~') {    /* it is printable */
  991. X        printable_code(c);
  992. X    } else {                    /* it is control */
  993. X        control_code(c);
  994. X    }
  995. X    
  996. X    return;
  997. X}
  998. X
  999. X/* it is a simple character */
  1000. Xprintable_code(c)
  1001. X    int c;
  1002. X{
  1003. X    BLANK(1, 1);            /* take away the cursor */
  1004. X    DrawChar(c);            /* paint in the character */
  1005. X    if(++vt_col >= MAXCOL) {    /* time to auto-linefeed */
  1006. X        vt_col = 0;
  1007. X        if(++vt_row >= MAXROW) {/* scroll it */
  1008. X            vt_row = MAXROW - 1; /* not so far please... */
  1009. X            vt_scroll();
  1010. X        }
  1011. X    }
  1012. X    HOP;                    /* move to the cell */
  1013. X    CURSOR;                    /* paint in the cursor */
  1014. X    
  1015. X    return;
  1016. X}
  1017. X
  1018. X/* process a control code - all are exactly 1 character in length */
  1019. Xcontrol_code(c)
  1020. X    int c;
  1021. X{
  1022. X    int i, j;
  1023. X    
  1024. X    switch(c) {
  1025. X      case '\007':            /* bell */
  1026. X        SysBeep(20);        /* beep for 20/60 seconds */
  1027. X        break;
  1028. X      case '\010':            /* backspace */
  1029. X        if(vt_col > 0) {    /* can't backspace past left margin */
  1030. X            CURSOR;            /* exor it again to remove */
  1031. X            vt_col--;
  1032. X            HOP;            /* jump back one */
  1033. X            CURSOR;            /* and a new cursor */
  1034. X        } else {
  1035. X            SysBeep(20);    /* be a pain */
  1036. X        }
  1037. X        break;
  1038. X      case '\011':            /* tab */
  1039. X        j = vt_col;            /* stack this for re-entrancy */
  1040. X        for(i = 0; i < (TABVAL - (j % TABVAL)); i++) {
  1041. X            vt_putch(' ');    /* just do some spaces */
  1042. X        }
  1043. X        break;
  1044. X      case '\012':            /* line feed */
  1045. X        CURSOR;                /* kill the old cursor */
  1046. X        if(!vt_rawf) {        /* do both cr and lf */
  1047. X            vt_col = 0;        /* the cr part is easy */
  1048. X        }
  1049. X        if(++vt_row >= MAXROW) {/* scroll it */
  1050. X            vt_row = MAXROW - 1; /* not so far please... */
  1051. X            vt_scroll();
  1052. X        }
  1053. X        HOP;
  1054. X        CURSOR;
  1055. X        break;
  1056. X      case '\015':            /* carriage return */
  1057. X        CURSOR;                /* kill the old cursor */
  1058. X        vt_col = 0;            /* the cr part is easy */
  1059. X        if(!vt_rawf) {        /* do both cr and lf */
  1060. X            if(++vt_row >= MAXROW) {/* scroll it */
  1061. X                vt_row = MAXROW - 1; /* not so far please... */
  1062. X                vt_scroll();
  1063. X            }
  1064. X        }
  1065. X        HOP;
  1066. X        CURSOR;
  1067. X        break;
  1068. X      case '\033':            /* escape */
  1069. X        vt_esc = EFIRST;        /* ok - start an escape sequence */
  1070. X        break;
  1071. X      /* the ones we don't handle come next */
  1072. X      case '\013':            /* vertical tab */
  1073. X      case '\014':            /* form feed */
  1074. X      default:
  1075. X        break;
  1076. X    } /* end of switch */
  1077. X    
  1078. X    return;
  1079. X}
  1080. X
  1081. Xescape_code(c)
  1082. X    int c;
  1083. X{
  1084. X    switch(vt_esc) {
  1085. X      case EFIRST:
  1086. X        switch(c) {
  1087. X          case '[':
  1088. X              vt_esc = EBRACKET; /* remember we saw it */
  1089. X            vt_inprog = vt_x = vt_y = 0; /* clear these */
  1090. X              break;
  1091. X            
  1092. X          default:
  1093. X              vt_esc = ENONE; /* blew it */
  1094. X              break;
  1095. X        }
  1096. X        break;
  1097. X      
  1098. X      case EBRACKET:
  1099. X        switch(c) {
  1100. X          case 'H': /* home (or motion) */
  1101. X              vt_x = vt_inprog; /* column number */
  1102. X            vt_inprog = 0;
  1103. X            /* adjust for brain damaged notion of screen starting at (1,1) */
  1104. X            if(--vt_x < 0) {
  1105. X                vt_x = 0;
  1106. X            }
  1107. X            if(--vt_y < 0) {
  1108. X                vt_y = 0;
  1109. X            }
  1110. X            CURSOR; /* take it away */
  1111. X            vt_row = vt_y;
  1112. X            vt_col = vt_x;
  1113. X            HOP;
  1114. X            CURSOR;
  1115. X            vt_esc = ENONE; /* code is complete */
  1116. X            break;
  1117. X            
  1118. X          case 'J': /* clear to end of screen */
  1119. X              if(vt_row + 1 < MAXROW) { /* something below us */
  1120. X                SAVE;
  1121. X                vt_row++;     /* drop down a row */
  1122. X                vt_col = 0;    /* and over to the beginning */
  1123. X                HOP;        /* actually move there */
  1124. X                BLANK(MAXCOL, MAXROW - vt_row);
  1125. X                RESTORE;
  1126. X                HOP;
  1127. X            }
  1128. X              /* fall through to clear the fractional part */
  1129. X          case 'K': /* clear to end of line */
  1130. X              BLANK(MAXCOL - vt_col, 1); /* erase all on the row */
  1131. X            CURSOR;    /* replace the cursor */
  1132. X            vt_esc = ENONE;
  1133. X              break;
  1134. X          
  1135. X          case '0': /* a row or column number */
  1136. X          case '1':
  1137. X          case '2':
  1138. X          case '3':
  1139. X          case '4':
  1140. X          case '5':
  1141. X          case '6':
  1142. X          case '7':
  1143. X          case '8':
  1144. X          case '9':
  1145. X              vt_inprog *= 10;         /* make room */
  1146. X            vt_inprog += c - '0';    /* add in the new digit */
  1147. X              break;
  1148. X            
  1149. X          case ';': /* end of row number */
  1150. X              vt_y = vt_inprog;
  1151. X            vt_inprog = 0;
  1152. X              break;
  1153. X            
  1154. X          default:
  1155. X              vt_esc = ENONE; /* blew it */
  1156. X              break;
  1157. X        }
  1158. X        break;
  1159. X        
  1160. X      default:
  1161. X          vt_esc = ENONE; /* blew it */
  1162. X          break;
  1163. X    }
  1164. X    
  1165. X    return;
  1166. X}
  1167. X
  1168. X/* low level reader - call this directly if you also want to use peek - that
  1169. X * way you get raw-mode and avoid all character buffers.  But note - this code
  1170. X * does NOT initialize the world first.  You must call vt_open() manually!
  1171. X */
  1172. Xvt_getch()
  1173. X{
  1174. X    EventRecord x;
  1175. X    int rc;
  1176. X    
  1177. X    SystemTask();
  1178. X    
  1179. X    /* GetNextEvent returns a boolean enum - make it an integer */
  1180. X    while(GetNextEvent(autoKeyMask | keyDownMask, &x) == false) {
  1181. X        SystemTask(); /* wait for it */
  1182. X    }
  1183. X    rc = x.message & 0xff;
  1184. X    if(x.modifiers & cmdKey) {    /* it is a control character */
  1185. X        rc &= 0x1f;                /* so fold it */
  1186. X    }
  1187. X    if(!vt_rawf && rc == '\004') { /* cooked mode and a ^D spells EOF */
  1188. X        return(EOF);
  1189. X    }
  1190. X    return(rc);
  1191. X}
  1192. X
  1193. X/* return a character but don't pull it off the queue!  Don't block if nothing is
  1194. X * available - just return a null.
  1195. X */
  1196. Xvt_peekch()
  1197. X{
  1198. X    EventRecord x;
  1199. X    int rc;
  1200. X    
  1201. X    SystemTask();
  1202. X    
  1203. X    /* EventAvail returns a boolean enum - make it an integer */
  1204. X    if(EventAvail(autoKeyMask | keyDownMask, &x) == true) { /* something */
  1205. X        rc = x.message & 0xff;
  1206. X        if(x.modifiers & cmdKey) {    /* it is a control character */
  1207. X            rc &= 0x1f;                /* so fold it */
  1208. X        }
  1209. X        if(!vt_rawf && rc == '\004') { /* cooked mode and a ^D spells EOF */
  1210. X            return(EOF);
  1211. X        } else {    /* normal character */
  1212. X            return(rc);
  1213. X        }
  1214. X        /*NOTREACHED*/
  1215. X    } else {
  1216. X        return(0);    /* nothing - call it a null */
  1217. X    }
  1218. X    /*NOTREACHED*/
  1219. X}
  1220. X
  1221. X/* handle system requests for open, rename, and delete.  Only open is legal.
  1222. X */
  1223. Xvt_faccess(fname, mode, perm)
  1224. X    char *fname;
  1225. X    int mode;
  1226. X    int perm;
  1227. X{
  1228. X    /* if we are not the correct driver, return and let the system try
  1229. X     * another driver.
  1230. X     */
  1231. X    if(EqualString(fname, "dev:console", false, true) == false) {
  1232. X        return(-1);
  1233. X    }
  1234. X    
  1235. X    /* this driver only handles opens */
  1236. X    if(mode == F_OPEN) {
  1237. X        if(firsttime == 0) { /* only do it once */
  1238. X            vt_open();
  1239. X            firsttime++;
  1240. X        }
  1241. X        return(0); /* but always claim success */
  1242. X    }
  1243. X    
  1244. X    /* tell them the request is bogus */
  1245. X    return(0x40000016);
  1246. X}
  1247. X
  1248. X/* not much to do */
  1249. Xvt_close()
  1250. X{
  1251. X    return(0);
  1252. X}
  1253. X
  1254. X/* return as many characters as asked for, up to a carriage return.  Someday
  1255. X * we need to add raw mode here.
  1256. X */
  1257. Xvt_read(ap)
  1258. X    IOSTR *ap;
  1259. X{
  1260. X    /* fill the buffer if it is empty */
  1261. X    if(linesize <= 0) {
  1262. X        linesize = vt_readline(linebuf, 256);
  1263. X        lineptr = linebuf;
  1264. X    }
  1265. X    
  1266. X    /* copy till either user is satisfied or we hit the end of the line.
  1267. X     * We must leave the count field set in the ap structure to show how
  1268. X     * much more is to be done.
  1269. X     */
  1270. X    for( ; (ap->count > 0) && (linesize > 0); ap->count--, linesize--) {
  1271. X        *(ap->buffer)++ = *lineptr++;
  1272. X    }
  1273. X    
  1274. X    return(0);
  1275. X}
  1276. X
  1277. X/* read until a carriage return (or we fill the buffer). Return how much we
  1278. X * got.
  1279. X */
  1280. Xvt_readline(bp, size)
  1281. X    char *bp;
  1282. X    int size;
  1283. X{
  1284. X    int i;
  1285. X    
  1286. X    for(i = size; i; bp++, i--) {
  1287. X        *bp = vt_getch();
  1288. X        
  1289. X        if(*bp == '\010' && i < size) {
  1290. X            bp -= 2;
  1291. X            i += 2;
  1292. X        }
  1293. X        
  1294. X        if(*bp == '\004' || *bp == '\n') {
  1295. X            i--;
  1296. X            break;
  1297. X        }
  1298. X    }
  1299. X    
  1300. X    return(size - i);
  1301. X}
  1302. X
  1303. X/* loop characters to the screen */
  1304. Xvt_write(ap)
  1305. X    IOSTR *ap;
  1306. X{
  1307. X    for( ; ap->count; ap->count--) { /* must leave count at 0 on exit */
  1308. X        vt_putch(*(ap->buffer)++);
  1309. X    }
  1310. X    
  1311. X    return(0);
  1312. X}
  1313. X
  1314. X/* this routine turns out to be essential because the system intends to ask us
  1315. X * for the optimum buffer size.  We return -1 to tell it to choose for us.
  1316. X */
  1317. Xvt_ioctl(fd, op, arg)
  1318. X    int fd;
  1319. X    int op;
  1320. X    int *arg;
  1321. X{
  1322. X    switch(op) {
  1323. X      case FIOINTERACTIVE:
  1324. X          return(0);
  1325. X        
  1326. X      case TIOFLUSH:
  1327. X          return(0);
  1328. X        
  1329. X      /* I don't trust this!  We would have to clear screen and reset
  1330. X       * point sizes for it to be safe.
  1331. X       */
  1332. X      case TIOSPORT:
  1333. X          /* vt = (WindowPtr) *arg; */
  1334. X          return(0);
  1335. X        
  1336. X      case TIOGPORT:
  1337. X          *arg = (int) vt;
  1338. X        return(0);
  1339. X        
  1340. X      default:
  1341. X          return(-1);
  1342. X    }
  1343. X    /*NOTREACHED*/
  1344. X}
  1345. X
  1346. X/* this stuff should be via ioctl but why make it so hard? */
  1347. Xvt_raw()
  1348. X{
  1349. X    vt_rawf = 1;
  1350. X    
  1351. X    return;
  1352. X}
  1353. X
  1354. Xvt_cooked()
  1355. X{
  1356. X    vt_rawf = 0;
  1357. X    
  1358. X    return;
  1359. X}
  1360. X
  1361. X/* this code is a reverse compile of the cruntime.o module. */
  1362. X/*
  1363. Xwrite(fd, buf, cnt)
  1364. X    int fd;
  1365. X    char *buf;
  1366. X    int cnt;
  1367. X{
  1368. X    IOSTR *ind;
  1369. X    int foo;
  1370. X    
  1371. X    if(fd < 0) {
  1372. X        _uerror(0x16, 0);
  1373. X        return(-1);
  1374. X    }
  1375. X    
  1376. X    ind = _getIOPort(&fd);
  1377. X    
  1378. X    if(!ind) {
  1379. X        return(-1);
  1380. X    }
  1381. X    
  1382. X    if(!(ind->flags & 2)) {
  1383. X        _uerror(0x09, 0);
  1384. X        return(-1);
  1385. X    }
  1386. X    
  1387. X    ind->count = cnt;
  1388. X    ind->buffer = buf;
  1389. X    foo = (*(ind->handler->l_write))(ind);
  1390. X    
  1391. X    if(foo) {
  1392. X        _uerror(foo, ind->errcode);
  1393. X        return(-1);
  1394. X    } else {
  1395. X        return(cnt - (ind->count));
  1396. X    }
  1397. X}
  1398. X*/
  1399. X
  1400. X/* this bypasses printf and is useful for debugging to avoid recursion.
  1401. X * Prints a string.
  1402. X */
  1403. X/*
  1404. Xlpr(s)
  1405. X    char *s;
  1406. X{
  1407. X    while(*s != 0) {
  1408. X        vt_putch(*s++);
  1409. X    }
  1410. X    
  1411. X    return;
  1412. X}
  1413. X*/
  1414. X
  1415. X/* this one prints an integer in hex with leading zeros. */
  1416. X/*
  1417. Xlpx(x)
  1418. X    unsigned int x;
  1419. X{
  1420. X    int i, j;
  1421. X    
  1422. X    for(i = 0; i < 8; i++) {
  1423. X        j = (x >> (28 - (i * 4))) & 0xf;
  1424. X        if(j <= 9) {
  1425. X            vt_putch(j + '0');
  1426. X        } else {
  1427. X            vt_putch(j - 10 + 'a');
  1428. X        }
  1429. X    }
  1430. X    
  1431. X    return;
  1432. X}
  1433. X*/
  1434. X
  1435. X/* Start of code for da support.  We use these for a gp text editor among
  1436. X * other things.  Note - there is no way to pass the file name in.  Oh
  1437. X * well.  Most of this code is stolen from the sample application which
  1438. X * Apple distributes with MPW and hence is copyright Apple Computer Corp.
  1439. X */
  1440. X
  1441. X/*
  1442. X * Resource ID constants.
  1443. X */
  1444. X# define appleID        128
  1445. X# define fileID         129
  1446. X# define editID         130
  1447. X
  1448. X# define appleMenu        0
  1449. X
  1450. X# define fileMenu        1
  1451. X# define    quitCommand     1
  1452. X
  1453. X# define editMenu        2
  1454. X# define    undoCommand     1
  1455. X# define    cutCommand        3
  1456. X# define    copyCommand     4
  1457. X# define    pasteCommand    5
  1458. X# define    clearCommand    6
  1459. X
  1460. X# define menuCount     3
  1461. X
  1462. X/*
  1463. X * HIWORD and LOWORD macros, for readability.
  1464. X */
  1465. X# define HIWORD(aLong)        (((aLong) >> 16) & 0xFFFF)
  1466. X# define LOWORD(aLong)        ((aLong) & 0xFFFF)
  1467. X
  1468. X/*
  1469. X * Global Data objects, used by routines external to main().
  1470. X */
  1471. XMenuHandle        MyMenus[menuCount];     /* The menu handles */
  1472. Xint                Doneflag;                /* Becomes TRUE when File/Quit chosen */
  1473. X
  1474. Xda_mode(fname)
  1475. X    char *fname;
  1476. X{
  1477. X    EventRecord     myEvent;
  1478. X    WindowPtr        theActiveWindow, whichWindow;
  1479. X    GrafPtr         savePort;
  1480. X    char            forcedDA[256];
  1481. X
  1482. X    setupMenus();
  1483. X
  1484. X    for (Doneflag = 0; !Doneflag; ) {
  1485. X        /*
  1486. X         * Main Event tasks:
  1487. X         */
  1488. X        SystemTask();
  1489. X        
  1490. X        /* if a name was passed in, assume it is a DA - we fake an open
  1491. X         * of it.  DA's are funny in that the name contains a leading
  1492. X         * NULL character.  So we stick one in 'cause they are hard to
  1493. X         * type.  This results in a bizzare C string but the Desk Manager
  1494. X         * is happy...
  1495. X         */
  1496. X        if(fname[0] != '\0') {
  1497. X            forcedDA[0] = '\0'; /* DA names (usually) have this */
  1498. X            strcpy(forcedDA + 1, fname); /* don't step on the null */
  1499. X            fname[0] = '\0';     /* open it only once */
  1500. X            GetPort(&savePort);
  1501. X            (void) OpenDeskAcc(forcedDA);
  1502. X            SetPort(savePort);
  1503. X            continue;
  1504. X        }
  1505. X                
  1506. X        theActiveWindow = FrontWindow();        /* Used often, avoid repeated calls */
  1507. X        /*
  1508. X         * Handle the next event.
  1509. X         */
  1510. X        if ( ! GetNextEvent(everyEvent, &myEvent)) {
  1511. X            continue;    /* not for us */
  1512. X        }
  1513. X        /*
  1514. X         * In the unlikely case that the active desk accessory does not
  1515. X         * handle mouseDown, keyDown, or other events, GetNextEvent() will
  1516. X         * give them to us!  So before we perform actions on some events,
  1517. X         * we check to see that the affected window in question is really
  1518. X         * our window.
  1519. X         */
  1520. X        switch (myEvent.what) {
  1521. X            case mouseDown:
  1522. X                switch (FindWindow(&myEvent.where, &whichWindow)) {
  1523. X                    case inSysWindow:
  1524. X                        SystemClick(&myEvent, whichWindow);
  1525. X                        break;
  1526. X                    case inMenuBar:
  1527. X                        doCommand(MenuSelect(&myEvent.where));
  1528. X                        break;
  1529. X                    case inDrag:
  1530. X                    case inGrow:
  1531. X                        /* No such - Fall through */
  1532. X                    case inContent:
  1533. X                        if (whichWindow != theActiveWindow) {
  1534. X                            SelectWindow(whichWindow);
  1535. X                        }
  1536. X                        break;
  1537. X                    default:
  1538. X                        break;
  1539. X                }/*endsw FindWindow*/
  1540. X                break;
  1541. X
  1542. X            case keyDown:
  1543. X            case autoKey:
  1544. X                if (vt == theActiveWindow) {
  1545. X                    if (myEvent.modifiers & cmdKey) {
  1546. X                        doCommand(MenuKey(myEvent.message & charCodeMask));
  1547. X                    }
  1548. X                }
  1549. X                break;
  1550. X
  1551. X            case activateEvt:
  1552. X                if ((WindowPtr) myEvent.message == vt) {
  1553. X                    if (myEvent.modifiers & activeFlag) {
  1554. X                        DisableItem(MyMenus[editMenu], 0);
  1555. X                    } else {
  1556. X                        EnableItem(MyMenus[editMenu], 0);
  1557. X                    }
  1558. X                    DrawMenuBar();
  1559. X                }
  1560. X                break;
  1561. X
  1562. X            default:
  1563. X                break;
  1564. X
  1565. X        }/*endsw myEvent.what*/
  1566. X
  1567. X    }/*endfor Main Event loop*/
  1568. X
  1569. X    trashMenus();
  1570. X    return;
  1571. X}
  1572. X
  1573. XsetupMenus()
  1574. X{
  1575. X    register MenuHandle *pMenu;
  1576. X    /*
  1577. X     * Set up the desk accessories menu.
  1578. X     *  We install the desk accessory names from the 'DRVR' resources.
  1579. X     */
  1580. X    MyMenus[appleMenu] = GetMenu(appleID);
  1581. X    AddResMenu(MyMenus[appleMenu], (ResType) 'DRVR');
  1582. X    /*
  1583. X     * Now the File and Edit menus.
  1584. X     */
  1585. X    MyMenus[fileMenu] = GetMenu(fileID);
  1586. X    MyMenus[editMenu] = GetMenu(editID);
  1587. X    /*
  1588. X     * Now insert all of the application menus in the menu bar.
  1589. X     *
  1590. X     * "Real" C programmers never use array indexes
  1591. X     * unless they're constants :-)
  1592. X     */
  1593. X    for (pMenu = &MyMenus[0]; pMenu < &MyMenus[menuCount]; ++pMenu) {
  1594. X        InsertMenu(*pMenu, 0);
  1595. X    }
  1596. X    DisableItem(MyMenus[editMenu], 0);
  1597. X
  1598. X    DrawMenuBar();
  1599. X
  1600. X    return;
  1601. X}
  1602. X
  1603. XtrashMenus()
  1604. X{
  1605. X    ClearMenuBar();        /* remove menus */
  1606. X    DrawMenuBar();        /* show it */
  1607. X    
  1608. X    ReleaseResource(MyMenus[appleMenu]);
  1609. X    ReleaseResource(MyMenus[fileMenu]);
  1610. X    ReleaseResource(MyMenus[editMenu]);
  1611. X
  1612. X    return;
  1613. X}
  1614. X
  1615. X/*
  1616. X * Process mouse clicks in menu bar
  1617. X */
  1618. XdoCommand(mResult)
  1619. Xlong mResult;
  1620. X{    
  1621. X    int                 theMenu, theItem;
  1622. X    char                daName[256];
  1623. X    GrafPtr             savePort;
  1624. X
  1625. X    theItem = LOWORD(mResult);
  1626. X    theMenu = HIWORD(mResult);        /* This is the resource ID */
  1627. X
  1628. X    switch (theMenu) {
  1629. X        case appleID:
  1630. X            GetItem(MyMenus[appleMenu], theItem, daName);
  1631. X            GetPort(&savePort);
  1632. X            (void) OpenDeskAcc(daName);
  1633. X            SetPort(savePort);
  1634. X            break;
  1635. X
  1636. X        case fileID:
  1637. X            switch (theItem) {
  1638. X                case quitCommand:
  1639. X                    Doneflag++;            /* Request exit */
  1640. X                    break;
  1641. X                default:
  1642. X                    break;
  1643. X            }
  1644. X            break;
  1645. X        case editID:
  1646. X            /*
  1647. X             * If this is for a 'standard' edit item,
  1648. X             * run it through SystemEdit.
  1649. X             */
  1650. X            if (theItem <= clearCommand) {
  1651. X                SystemEdit(theItem-1);
  1652. X            }
  1653. X            break;
  1654. X
  1655. X        default:
  1656. X            break;
  1657. X
  1658. X    }/*endsw theMenu*/
  1659. X
  1660. X    HiliteMenu(0);
  1661. X
  1662. X    return;
  1663. X}
  1664. END_OF_FILE
  1665. if test 19069 -ne `wc -c <'mac-vt.c'`; then
  1666.     echo shar: \"'mac-vt.c'\" unpacked with wrong size!
  1667. fi
  1668. # end of 'mac-vt.c'
  1669. fi
  1670. echo shar: End of archive 9 \(of 15\).
  1671. cp /dev/null ark9isdone
  1672. MISSING=""
  1673. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ; do
  1674.     if test ! -f ark${I}isdone ; then
  1675.     MISSING="${MISSING} ${I}"
  1676.     fi
  1677. done
  1678. if test "${MISSING}" = "" ; then
  1679.     echo You have unpacked all 15 archives.
  1680.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1681. else
  1682.     echo You still need to unpack the following archives:
  1683.     echo "        " ${MISSING}
  1684. fi
  1685. ##  End of shell archive.
  1686. exit 0
  1687.  
  1688.